package controllers;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

import models.Minimap;
import models.Player;
import models.Stage;
import models.entity.Entity;
import models.power.Power;
import models.tent.Tent;
import models.tile.Tile;
import controllers.managers.TentGenerator;
import controllers.managers.TroopGenerator;

@SuppressWarnings("serial")
public class Game extends JPanel implements Runnable{
	
	public Player player1;
	public Player player2;
	public Stage stage;
	public int turn;
	public int ind;
	public int nRows, nCols;
	

	public boolean running;
	public ArrayList<Entity> entities = new ArrayList<Entity>();
	public ArrayList<Tent> tents = new ArrayList<>();
	public TroopGenerator tg = new TroopGenerator(this);
	public TentGenerator tentG = new TentGenerator(this);
	
	public Timer timer;

	public Minimap minimap = new Minimap();
	private GameIA gameIA;
	
	
	public final static String NAME = "Ultimate conquest";
	public final static int HEIGHT = 600;
	public final static int HEIGHTSTAGE = 400;
	public final static int WIDTH = 800;
	
	
	public Game(int nRows, int nCols, int nTroops){
		player1 = new Player(this, 1, nTroops);
		player2 = new Player(this, 2, nTroops);
		
		
		stage = new Stage();
		stage.createMap(nCols, nRows, this);
		
		minimap.createMinimap(this);
		
		
		this.nRows = nRows;
		this.nCols = nCols;
				
		//TODO The turn field must to be a variable in future iterations
		turn =  25;
		
		timer = new Timer(this);
		
	}
	
	public void init(){
		
		ind = 0;
		
		gameIA = new GameIA(this);
		new Thread(gameIA).start();
	}
	


	public void paint(Graphics g){
		
		super.paint(g);
		Graphics2D g2d = (Graphics2D) g;
		
        g2d.fillRect(0,0,getWidth(),getHeight());
		
		
        // Drawing background
        @SuppressWarnings("unchecked")
		ArrayList<Tile> stageAux = (ArrayList<Tile>) stage.getStage().clone();
        for(Tile t:stageAux){
        	t.draw(g2d);
        }
        
            
 
		//Skim all the entities and draw them
        @SuppressWarnings("unchecked")
		ArrayList<Entity> ae = (ArrayList<Entity>) entities.clone();
		for(Entity entity:ae){
			entity.update();
			@SuppressWarnings("unchecked")
			ArrayList<Power> ap = (ArrayList<Power>) entity.getPowers().clone();
			entity.draw(g2d);
			for(Power power:ap){
				power.draw(g2d);
			}
		}
		
		//Skim all the tents and draw them
		@SuppressWarnings("unchecked")
		ArrayList<Tent> at = (ArrayList<Tent>) tents.clone();
		for(Tent tent:at){
			tent.draw(g2d);
		}
		
		
		try {
			Thread.sleep(2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		minimap.createMinimap(this);
		minimap.repaint();
		
		timer.repaint();
		
		
	}

	public void newGame(){	
		this.init();
		new Thread(this).start();
	}
	
	public void gameOver(int i){
		if(i==0){
			JOptionPane.showMessageDialog(this, "Game Over", "Game Over, the winner is Player2", JOptionPane.YES_NO_OPTION);
		}else if(i==1){
			JOptionPane.showMessageDialog(this, "Game Over", "Game Over, the winner is Player1", JOptionPane.YES_NO_OPTION);
		}
		
		System.exit(ABORT);
	}

	@Override
	public void run() {
		
		while(true){
			
			//TODO Actualize background
			
			//Actualize player position
			moveEntities();
			
			//Actualize the entire Component
			repaint();
			
			if(player1.health<=0){
				gameOver(0);
			}else if(player2.health<=0){
				gameOver(1);
			}
			
			//This sentence is needed to give a breath to the run stub
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				System.out.print("Error catching the Exception in run()");
				e.printStackTrace();
			}
		}
	}
	
	
	
	public void moveEntities() {
		@SuppressWarnings("unchecked")
		ArrayList<Entity> entAux = (ArrayList<Entity>) entities.clone();
		for(Entity ent:entAux){
			ent.move();
		}
	}


	public void main(){
		this.newGame();	
	}
	
	public int entityIsInTile(int x, int y) {
		int player = -1;
		
		@SuppressWarnings("unchecked")
		ArrayList<Entity> ae = (ArrayList<Entity>) entities.clone();
		for(Entity entity:ae){
			if(entity.getPosXTile()==x && entity.getPosYTile()==y && entity.getCurrentlyStatus() != 2){
				player = entity.getPlayer().color;
			}
		}
		return player;
	}
	
	public int tentIsInTile(int x, int y) {
		int player = -1;
		
		@SuppressWarnings("unchecked")
		ArrayList<Tent> at = (ArrayList<Tent>) tents.clone();
		for(Tent tent:at){
			if(tent.nTileX==x && tent.nTileY==y){
				player = tent.player.color;
			}
		}
		return player;
	}

	public void stop() {
		running = false;
		
	}

	public void setTentInTile(int x, int y, Tent tent, int player) {
		tentG.addTent(x, y, tent, player);
	}

	public void addTroopToPlayer(int color) {
		if(color == 0){
			player1.numTroops++;
			player1.resources -= 500;
		}else if(color == 1){
			player2.numTroops++;
			player2.resources -= 500;
		}
	}
	
	public int getInd() {
		return ind;
	}

	public void setInd(int ind) {
		this.ind = ind;
	}
}
